package com.xbongbong.paas.service.team.strategy;

import com.alibaba.fastjson.JSONArray;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.dynamic.crm.strategy.TeamDynamicStrategy;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.parent.interfaces.TeamStrategy;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailEditLabelDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailUpdateDTO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailEditCoPerVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailEditLabelVO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicTeamLabelDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicTeamUpdateDTO;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.teammembers.enums.CoUserPermissionEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormCoUserDefaultPermissionEnum;
import com.xbongbong.pro.team.TeamAfterFormatDTO;
import com.xbongbong.pro.team.TeamAfterVerifyDTO;
import com.xbongbong.pro.team.TeamVerifyDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.ContactUserEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContactUserModel;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.elasticsearch.action.support.WriteRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author shen.yang
 * @version v1.0
 * @Description 联系人团队 策略实现
 * @date 2022/1/14 16:23
 * @since v1.0
 */
@Service
public class ContactTeamStrategy extends AbstractTeamStrategy implements TeamStrategy {
    @Resource
    private ContactUserModel contactUserModel;
    @Resource
    private ContactModel contactModel;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.CONTACT.getCode(), XbbRefTypeEnum.DISTRIBUTOR_CONTACT.getCode());
    }

    @Override
    public TeamAfterVerifyDTO verify(TeamVerifyDTO teamVerifyDTO) throws XbbException {
        return super.verifyTeam(teamVerifyDTO);
    }

    @Override
    public TeamAfterVerifyDTO specialVerify(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        return teamAfterVerifyDTO;
    }

    @Override
    public void save(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        String corpid = teamAfterVerifyDTO.getCorpid();
        List<Long> dataId = teamAfterVerifyDTO.getDataId();
        Integer businessType = teamAfterVerifyDTO.getBusinessType();
        TeamAfterFormatDTO teamAfterFormatDTO = formatTeam(teamAfterVerifyDTO);

        LinkedHashMap<String, Integer> esWait = judgeTeamEsWait(teamAfterFormatDTO);

        for (Iterator<Map.Entry<String, Integer>> iterator = esWait.entrySet().iterator(); iterator.hasNext(); ) {
            Map.Entry<String, Integer> entry = iterator.next();
            boolean hasNext = iterator.hasNext();
            switch (entry.getKey()) {
                case TeamMembersConstant.ADD_USER:
                    List<UserTeamEntity> addUserTeamList = teamAfterFormatDTO.getAddUserTeamList();
                    if (CollectionsUtil.isNotEmpty(addUserTeamList)) {
                        List<ContactUserEntity> contactUserEntityList = new ArrayList<>();
                        try {
                            BeanUtil.copyPropertiesList(addUserTeamList, contactUserEntityList, ContactUserEntity.class, false);
                        } catch (Exception e) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                        }
                        // 联系人团队插入客户id不可为null
                        List<PaasFormDataEntityExt> byDataIdList = formDataHelp.getByDataIdList(dataId, businessType, SaasMarkEnum.SAAS.getCode(), null, corpid);
                        //获取dataId -> customerId 映射关系
                        Map<Long,Long> result =  byDataIdList.stream().collect(Collectors.toMap(t -> t.getDataId(), v -> {
                            try {
                                return FastJsonHelper.getLongOrDefaultFromFormData(v.getData(), ContactEnum.CUSTOMER_NAME.getAttr(), 0L);
                            } catch (XbbException e) {

                            }
                            return 0L;
                        }));
                        contactUserEntityList.forEach(v -> {
                            v.setCustomerId(result.get(v.getDataId()));
                        });

                        if (hasNext) {
                            contactUserModel.insertBatch(contactUserEntityList, true);
                        } else {
                            contactUserModel.insertBatch(contactUserEntityList, false);
                        }
                    }
                    break;
                case TeamMembersConstant.DEL_USER:
                    List<UserTeamEntity> delUserTeamList = teamAfterFormatDTO.getDelUserTeamList();
                    if (CollectionsUtil.isNotEmpty(delUserTeamList)) {
                        List<Long> idIn = delUserTeamList.stream().map(UserTeamEntity::getId).collect(Collectors.toList());
                        if (hasNext) {
                            contactUserModel.batchUpdateByUserIdIn(corpid, idIn, delUserTeamList, null, DelEnum.DELETE.getDel(), WriteRequest.RefreshPolicy.NONE);
                        } else {
                            contactUserModel.batchUpdateByUserIdIn(corpid, idIn, delUserTeamList, null, DelEnum.DELETE.getDel(), WriteRequest.RefreshPolicy.WAIT_UNTIL);
                        }
                    }
                    break;
                case TeamMembersConstant.TO_MAIN_USER:
                    List<UserTeamEntity> updateUserToMainTeamList = teamAfterFormatDTO.getUpdateUserToMainTeamList();
                    if (CollectionsUtil.isNotEmpty(updateUserToMainTeamList)) {
                        List<Long> idIn = updateUserToMainTeamList.stream().map(UserTeamEntity::getId).collect(Collectors.toList());
                        if (hasNext) {
                            contactUserModel.batchUpdateByUserIdIn(corpid, idIn, updateUserToMainTeamList, BasicConstant.MAIN_USER, DelEnum.NORMAL.getDel(), WriteRequest.RefreshPolicy.NONE);
                        } else {
                            contactUserModel.batchUpdateByUserIdIn(corpid, idIn, updateUserToMainTeamList, BasicConstant.MAIN_USER, DelEnum.NORMAL.getDel(), WriteRequest.RefreshPolicy.WAIT_UNTIL);
                        }
                    }
                    break;
                case TeamMembersConstant.TO_CO_USER:
                    List<UserTeamEntity> updateUserToCoTeamList = teamAfterFormatDTO.getUpdateUserToCoTeamList();
                    if (CollectionsUtil.isNotEmpty(updateUserToCoTeamList)) {
                        List<Long> idIn = updateUserToCoTeamList.stream().map(UserTeamEntity::getId).collect(Collectors.toList());
                        if (hasNext) {
                            contactUserModel.batchUpdateCoAndPerByUserIdIn(corpid, idIn, updateUserToCoTeamList, BasicConstant.COOP_USER, false, WriteRequest.RefreshPolicy.NONE);
                        } else {
                            contactUserModel.batchUpdateCoAndPerByUserIdIn(corpid, idIn, updateUserToCoTeamList, BasicConstant.COOP_USER, false, WriteRequest.RefreshPolicy.WAIT_UNTIL);
                        }
                    }
                    break;
                case TeamMembersConstant.UPDATE_USER:
                    break;
                default:
            }
        }
    }

    @Override
    public void afterSave(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException{
        String corpid = teamAfterVerifyDTO.getCorpid();
        List<Long> dataId = teamAfterVerifyDTO.getDataId();
        long now = DateTimeUtil.getInt();
        //更新时间
        List<UpdateDataEntity> updateDataEntities = new ArrayList<>();
        dataId.forEach(v -> {
            UpdateDataEntity updateDataEntity = new UpdateDataEntity();
            updateDataEntity.setUpdateTime(now+1);
            updateDataEntity.setId(v);
            updateDataEntity.setCorpid(corpid);
            updateDataEntities.add(updateDataEntity);
        });
        contactModel.updateBatch(updateDataEntities,corpid, WriteRequest.RefreshPolicy.NONE);

    }

    @Override
    public void log(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        super.log(teamAfterVerifyDTO);
    }

    @Override
    public TeamDetailEditCoPerVO editCoPermission(TeamDetailUpdateDTO teamDetailUpdateDTO) throws XbbException {
        TeamDetailEditCoPerVO teamDetailEditCoPerVO = new TeamDetailEditCoPerVO();
        Long dataId = teamDetailUpdateDTO.getDataId();
        String corpid = teamDetailUpdateDTO.getCorpid();
        Long id = teamDetailUpdateDTO.getId();
        //编辑协同人权限
        Integer formPermission = teamDetailUpdateDTO.getFormPermission();
        ContactUserEntity shouldUpdateEntity = contactUserModel.getByKey(id, corpid);
        if(Objects.nonNull(shouldUpdateEntity)){
            Integer dbFormPermission = shouldUpdateEntity.getFormPermission();
            if (Objects.isNull(dbFormPermission)) {
                dbFormPermission = FormCoUserDefaultPermissionEnum.getDefaultPerByBus(teamDetailUpdateDTO.getBusinessType());
            }
            if (!Objects.equals(formPermission, dbFormPermission)) {
                shouldUpdateEntity.setFormPermission(formPermission);
                contactUserModel.updateEditFormPer(shouldUpdateEntity);
                contactModel.updateTime(dataId,corpid);
                String content = "";
                if (Objects.equals(formPermission, CoUserPermissionEnum.EDIT.getPermissionValue())) {
                    content = I18nMessageUtil.getMessage(TeamMembersConstant.EDIT);
                }else {
                    content = I18nMessageUtil.getMessage(TeamMembersConstant.NO_EDIT);
                }
                ContactEntityExt contactEntityExt = contactModel.getByKey(dataId, corpid);
                saveUpdateCoPerLogger(teamDetailUpdateDTO.getLoginUser(), teamDetailUpdateDTO.getFormId(), shouldUpdateEntity.getUserId(),
                        corpid, teamDetailUpdateDTO.getBusinessType(), contactEntityExt,  content, teamDetailUpdateDTO.getHttpHeader());

                TeamDynamicStrategy teamDynamicStrategy = dynamicStrategyFactory.getTeamDynamicStrategyByBusinessType(teamDetailUpdateDTO.getBusinessType());
                teamDynamicStrategy.saveUpdateCoPerDynamic(DynamicTeamUpdateDTO.initDynamicTeamUpdateDTO(teamDetailUpdateDTO, BeanUtil.copyProperties(shouldUpdateEntity, UserTeamEntity.class, true)));
            }
        }
        return teamDetailEditCoPerVO;
    }

    @Override
    public TeamDetailEditLabelVO editLabel(TeamDetailEditLabelDTO teamDetailEditLabelDTO) throws XbbException {
        TeamDetailEditLabelVO teamDetailEditLabelVO = new TeamDetailEditLabelVO();
        String corpid = teamDetailEditLabelDTO.getCorpid();
        Long id = teamDetailEditLabelDTO.getId();
        Long dataId = teamDetailEditLabelDTO.getDataId();
        JSONArray labels = teamDetailEditLabelDTO.getLabels();
        ContactUserEntity contactUserEntity = contactUserModel.getByKey(id, corpid);
        JSONArray dbLabels = contactUserEntity.getLabels();
        List<Long> lbIdFormList = new ArrayList<>();
        List<Long> lbIdSysList = new ArrayList<>();
        List<Long> dbLbIdFormList = new ArrayList<>();
        List<Long> dbLbIdSysList = new ArrayList<>();
        boolean addTag = userTeamHelp.getAddLogTag(labels, dbLabels, lbIdFormList, lbIdSysList, dbLbIdFormList, dbLbIdSysList);
        if (addTag) {
            contactUserEntity.setLabels(labels);
            contactUserModel.editLabel(contactUserEntity);
            //更新主业务的更新时间
            contactModel.updateTime(dataId,corpid);
            ContactEntityExt contactEntityExt = contactModel.getByKey(dataId, corpid);
            //记录日志信息
            saveUpdateLabelLogger(teamDetailEditLabelDTO.getLoginUser(), teamDetailEditLabelDTO.getFormId(), contactUserEntity.getUserId(), corpid,
                    teamDetailEditLabelDTO.getBusinessType(), contactEntityExt, contactUserEntity.getIsMain(), teamDetailEditLabelDTO.getHttpHeader(),
                    lbIdFormList, lbIdSysList, dbLbIdFormList, dbLbIdSysList, contactUserEntity.getUpdateTime());

            TeamDynamicStrategy teamDynamicStrategy = dynamicStrategyFactory.getTeamDynamicStrategyByBusinessType(teamDetailEditLabelDTO.getBusinessType());
            teamDynamicStrategy.saveUpdateLabelDynamic(DynamicTeamLabelDTO.initDynamicTeamLabelDTO(teamDetailEditLabelDTO, contactUserEntity));
        }
        return teamDetailEditLabelVO;
    }
}
